package br.com.foxinline.servico;

import br.com.foxinline.generico.ServicoGenerico;
import br.com.foxinline.modelo.Anexo;
import br.com.foxinline.modelo.Bairro;
import br.com.foxinline.modelo.Coordenada;
import br.com.foxinline.modelo.Localidade;
import java.beans.Transient;
import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.NoResultException;
import javax.persistence.Query;

/**
 *
 * @author laverson
 */
@Stateless
public class LocalidadeServico extends ServicoGenerico<Localidade> {

    private Long quantidadeRegistrosResults;

    public LocalidadeServico() {
        super(Localidade.class);
    }

    @Override
    public void update(Localidade entity) {
        super.update(entity);
        updateAnexos(entity);
    }

    @Override
    public void updateAnexos(Localidade p) {
        p.setAnexo(getAnexo(p));
        super.updateAnexos(p);
    }

    private Anexo getAnexo(Localidade l) {
        String sql = "SELECT a FROM Localidade l JOIN l.anexo a WHERE l.id = :id and a.ativo = true ORDER BY a.id ";
        Query query = getEntityManager().createQuery(sql);
        query.setParameter("id", l.getId());

        try {
            return (Anexo) query.getSingleResult();
        } catch (NoResultException e) {
            return null;
        }
    }

    @Override
    public List<Localidade> findAll() {
        return getEntityManager().createQuery("select l from " + Localidade.class.getSimpleName() + " l "
                + "where l.ativo = true").getResultList();
    }

    public List<Localidade> autoComplete(String query) {
        return findByName(query);
    }

    public List<Localidade> findByName(String query) {
        String sql = "select e from " + Localidade.class.getSimpleName() + " e where lower(e.nome) like '%" + query.toLowerCase().trim() + "%'";

        Query querye = getEntityManager().createQuery(sql);

        return querye.getResultList();
    }

    public List<Localidade> findByName(String query, Bairro bairro) {
        String sql = "select l from " + Localidade.class.getSimpleName() + " l ";

        if (bairro != null && bairro.getNome() != null && !bairro.getNome().equals("")) {
            sql += " JOIN l.bairro b ";
        }

        sql += "where lower(l.nome) like lower(:nome)";

        if (bairro != null && bairro.getNome() != null && !bairro.getNome().equals("")) {
            sql += " and lower(b.nome) like lower(:nomeBairro)";
        }

        Query querya = getEntityManager().createQuery(sql);

        if (bairro != null && bairro.getNome() != null && !bairro.getNome().equals("")) {
            querya.setParameter("nome", "%" + query.trim().replace(" ", "%") + "%");
        }

        if (bairro != null && bairro.getNome() != null && !bairro.getNome().equals("")) {
            querya.setParameter("nomeBairro", "%" + bairro.getNome() + "%");
        }

        return querya.getResultList();
    }

    public List<Coordenada> lstCoordenadaBairro(Localidade localidade) {
        String sql = "select c from Localidade l JOIN l.coordenadas c WHERE l.id = :id order by c.id";

        Query query = getEntityManager().createQuery(sql);
        query.setParameter("id", localidade.getId());

        return query.getResultList();
    }

    @Override
    public List<Localidade> find(Localidade entidade, Integer first, Integer pageSize) {
        String select = "select l ";
        String sql = "from Localidade l ";
        String orderBy = " order by l.nome ASC";

        Bairro bairro = entidade.getBairro() != null ? entidade.getBairro() : null;

        if (bairro != null) {
            sql += " JOIN l.bairro b ";
        }

        sql += " WHERE ";

        if (entidade.getNome() != null && !entidade.getNome().equals("")) {
            sql += " lower(l.nome) like lower(:nome) and ";
        }

        if (bairro != null) {
            sql += " b.id = :bairro and ";
        }

        sql += " 1=1 ";

        Query query = getEntityManager().createQuery(select.concat(sql).concat(orderBy));

        setQuantidadeRegistros(sql, bairro, entidade, query);

        setParameters(bairro, entidade, query);

        query.setFirstResult(first).setMaxResults(pageSize);

        return query.getResultList();
    }

    @Transient
    private void setParameters(Bairro bairro, Localidade entidade, Query query) {
        if (bairro != null) {
            query.setParameter("bairro", bairro.getId());
        }

        if (entidade.getNome() != null && !entidade.getNome().equals("")) {
            query.setParameter("nome", "%" + entidade.getNome() + "%");
        }
    }

    private void setQuantidadeRegistros(String sql, Bairro bairro, Localidade entidade, Query query) {

        String select = "SELECT count(b) ";

        query = getEntityManager().createQuery(select + sql);

        setParameters(bairro, entidade, query);

        quantidadeRegistrosResults = (Long) query.getSingleResult();
    }

    @Override
    public Long quantidadeRegistros() {
        return quantidadeRegistrosResults;
    }
}
